package com.mornd.gulimall.ware.receiver;

import com.mornd.gulimall.apis.order.to.OrderTo;
import com.mornd.gulimall.apis.ware.to.MqStockLockedTo;
import com.mornd.gulimall.ware.service.IWareSkuService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @author: mornd
 * @dateTime: 2023/8/27 - 8:21
 * 库存解锁
 */

@Slf4j
@Component
@RabbitListener(queues = {"stock.release.queue", "order.release.other.queue"})
public class SkuStockLockedReceiver {
    @Resource
    private IWareSkuService wareSkuService;

    /**
     * 库存解锁
     * 两种情况
     * 1、用户下单成功，订单超时未支付，自动取消
     * 2、下单逻辑出问题，代码调用发生异常
     *
     * @param message
     * @param to
     * @param channel
     */
    @RabbitHandler // 根据方法参数类型来决定接收哪个队列的消息
    public void handle(Message message, MqStockLockedTo to, Channel channel) throws IOException {
        // 消息是否是重新派发过来的
        Boolean redelivered = message.getMessageProperties().getRedelivered();
        log.debug("收到解锁库存消息1，{}", to.toString());
        try {
            wareSkuService.unlock(to);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error(e.getMessage());
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }
    }

    /**
     * 解决网络卡顿，导致先解锁库存，后取消订单的问题
     *
     * @param message
     * @param to
     * @param channel
     * @throws IOException
     */
    @RabbitHandler
    public void handleOrderClose(Message message, OrderTo to, Channel channel) throws IOException {
        log.debug("收到解锁库存消息2，{}", to.toString());
        try {
            wareSkuService.unlock(to);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error(e.getMessage());
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }
    }
}
